package stundenplan;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;

import utils.MyHtmlClient;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ViewFlipper;
import database.AppDatabase;
import database.StundenplanDatabaseService;
import de.app.badresden.AnimationTouchListener;
import de.app.badresden.IDatePickerActivity;
import de.app.badresden.R;

public class StundenplanActivity extends Activity implements OnClickListener,
		IDatePickerActivity,OnCancelListener {

	private ProgressDialog progressdialog;
	private StundenplanDatabaseService dbService;
	private StundenplanScreenBuilder stundenplanScreenBuilder;
	private Calendar cal = Calendar.getInstance();
	private Button datePickerButton;
	private ViewFlipper viewflipper;
	private LinearLayout flipperone;
	private LinearLayout flippertwo;
	private boolean flipperOneActive = true;
	private SharedPreferences preferences;
	private boolean internet;

	public void onCreate(Bundle icicle) {

		super.onCreate(icicle);

		internet = getIntent().getExtras().getBoolean("HasInternet");
		
		if (internet) progressdialog = ProgressDialog.show(StundenplanActivity.this,
				getString(R.string.progressdialog_title),
				getString(R.string.progressdialog_stundenplan),true, true, this);
		else
			progressdialog = ProgressDialog.show(StundenplanActivity.this,
					getString(R.string.progressdialog_title),
					getString(R.string.progressdialog_database), true, true, this);

		preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
		dbService = new StundenplanDatabaseService(
				new AppDatabase(getApplicationContext()).getWritableDatabase());

		Thread stundenplanImportThread = new Thread() {

			public void run() {

				try {
					synchronized (this) {
						List<Unterrichtstag> unterrichtstage = null;

						if (internet) {
							unterrichtstage = importNextWeeks(getIntent().getExtras()
									.getString("cookievalue"), preferences.getInt(
									"anzahl_importweeks", 1));
						}
						else {
							unterrichtstage = dbService.getUnterrichtstage();
							Thread.sleep(5000);
						}

						Bundle bundle = new Bundle();
						bundle.putSerializable("unterrichtstage",
								(Serializable) unterrichtstage);
						Message msg = new Message();
						msg.setData(bundle);
						updateHandler.sendMessage(msg);
					}
				}
				catch (Exception e) {
					Log.d("badresden app", e.toString());
				}
			}
		};
		stundenplanImportThread.start();
	}

	private Handler updateHandler = new Handler() {

		@SuppressWarnings("unchecked")
		public void handleMessage(Message msg) {

			super.handleMessage(msg);

			Bundle bundle = msg.getData();
			ArrayList<Unterrichtstag> unterrichtstage = (ArrayList<Unterrichtstag>) bundle
					.getSerializable("unterrichtstage");

			if (preferences.getBoolean("save_data", false) && internet) 
				dbService.insertUnterrichtstage(unterrichtstage);

			setContentView(R.layout.stundenplan_layout);

			datePickerButton = (Button) findViewById(R.id.stundenplanlayout_datePickerBtn);
			viewflipper = (ViewFlipper) findViewById(R.id.stundenplan_layoutswitcher);
			flipperone = (LinearLayout) findViewById(R.id.stundenplan_flipperone);
			flippertwo = (LinearLayout) findViewById(R.id.stundenplan_flippertwo);

			AnimationTouchListener touchListener = new AnimationTouchListener(
					StundenplanActivity.this, viewflipper);
			datePickerButton.setOnClickListener(StundenplanActivity.this);
			viewflipper.setOnTouchListener(touchListener);

			stundenplanScreenBuilder = new StundenplanScreenBuilder(StundenplanActivity.this,touchListener);
			stundenplanScreenBuilder.ImportUnterrichtstage(unterrichtstage);
			stundenplanScreenBuilder.updateStundenplan(cal, flipperone);

			updateDatePickerButton();
			progressdialog.dismiss();
		}
	};


	@Override
	public void onClick(View clickedButton) {

		if (clickedButton == datePickerButton) {
			showDialog(0);
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {

		return new DatePickerDialog(this, DatePickerListener, cal.get(Calendar.YEAR),
				cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH));
	}

	private DatePickerDialog.OnDateSetListener DatePickerListener = new DatePickerDialog.OnDateSetListener() {

		@Override
		public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {

			cal.set(year, monthOfYear, dayOfMonth);
			updateDatePickerButton();
			updateActiveView();
		}
	};

	@Override
	public void updateDatePickerButton() {

		Locale loc = getBaseContext().getResources().getConfiguration().locale;
		SimpleDateFormat dayformat = new SimpleDateFormat("EEEE", loc);
		SimpleDateFormat monthformat = new SimpleDateFormat("MMM", loc);

		String dateText = dayformat.format(cal.getTime()) + ", "
				+ String.valueOf(cal.get(Calendar.DAY_OF_MONTH)) + ". "
				+ monthformat.format(cal.getTime()) + " "
				+ String.valueOf(cal.get(Calendar.YEAR));

		datePickerButton.setText(dateText);
	}

	@Override
	public void updateNextView() {

		if (flipperOneActive) {
			stundenplanScreenBuilder.updateStundenplan(cal, flippertwo);
			flipperOneActive = false;
		}
		else {
			stundenplanScreenBuilder.updateStundenplan(cal, flipperone);
			flipperOneActive = true;
		}
	}

	@Override
	public void updateActiveView() {

		if (flipperOneActive) stundenplanScreenBuilder.updateStundenplan(cal, flipperone);
		else
			stundenplanScreenBuilder.updateStundenplan(cal, flippertwo);
	}

	public TextView getView(int id) {

		return (TextView) findViewById(id);
	}

	@Override
	public void addDay() {

		cal.add(Calendar.DAY_OF_MONTH, 1);
	}

	@Override
	public void subDay() {

		cal.add(Calendar.DAY_OF_MONTH, -1);
	}

	private List<Unterrichtstag> importNextWeeks(String cookievalue, int anz_weeks) {

		HttpPost postmethod = new HttpPost(getString(R.string.url_stundenplan));
		
		String htmlString = new MyHtmlClient().getHtmlString(null, cookievalue, postmethod);

		List<Unterrichtstag> list = new StundenplanImport(htmlString).getStundenplan();

		for (int i = 0; i < anz_weeks; i++) {

			ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
			postParameters.add(new BasicNameValuePair("kwn", "%3E"));
			postParameters.add(new BasicNameValuePair("sel_dat",
					getPostParameterForWeekselection(i)));

			UrlEncodedFormEntity formEntity = null;
			try {
				formEntity = new UrlEncodedFormEntity(postParameters);
			}
			catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}	
			
			postmethod.setEntity(formEntity);
			list.addAll(new StundenplanImport( new MyHtmlClient().getHtmlString(null, cookievalue, postmethod)).getStundenplan());
		}
		return list;
	}

	private String getPostParameterForWeekselection(int i) {

		SimpleDateFormat parameterFormat = new SimpleDateFormat("dd.MM.yyyy");

		final GregorianCalendar calendar = new GregorianCalendar();
		calendar.clear();
		calendar.set(Calendar.YEAR, cal.get(Calendar.YEAR));
		calendar.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR));
		calendar.setFirstDayOfWeek(1);

		for (int m = 0; m < i; m++) {
			calendar.add(Calendar.WEEK_OF_YEAR, 1);
		}

		calendar.add(Calendar.DAY_OF_MONTH, 1);
		Date start = calendar.getTime();
		calendar.add(Calendar.DAY_OF_MONTH, 6);
		Date end = calendar.getTime();

		return parameterFormat.format(start) + "+-+" + parameterFormat.format(end);
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		dbService.close();
	}

	@Override
	public void onCancel(DialogInterface arg0) {
		progressdialog.dismiss();
		finish();
	}
}